package com.ruoyi.web.controller.fs;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.util.*;
import javax.servlet.http.HttpServletResponse;

import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.fs.domain.*;
import com.ruoyi.fs.service.*;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.web.controller.tool.ExcelExporter;
import com.ruoyi.web.controller.tool.OSSUtil;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;

/**
 * 还款计划支付Controller
 *
 * @author hero
 * @date 2024-11-18
 */
@RestController
@RequestMapping("/fs/pay")
public class FsCaseRepaymentSchedulePayController extends BaseController {
    @Autowired
    private IFsCaseRepaymentSchedulePayService fsCaseRepaymentSchedulePayService;
    @Autowired
    private IFsCaseRepaymentScheduleService fsCaseRepaymentScheduleService;
    @Autowired
    private IFsCaseRepaymentScheduleFileService fsCaseRepaymentScheduleFileService;
    @Autowired
    private IFsRepaymentStatisticService fsRepaymentStatisticService;
    @Autowired
    private IFsCaseService fsCaseService;
    @Autowired
    private IFsClientService fsClientService;
    @Autowired
    private IFsEntrustService fsEntrustService;
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private OSSUtil ossUtil;

    /**
     * 查询还款计划支付列表
     */
    @PreAuthorize("@ss.hasPermi('fs:case:list')")
    @GetMapping("/list")
    public TableDataInfo list(FsCaseRepaymentSchedulePay fsCaseRepaymentSchedulePay) {
        startPage();
        List<FsCaseRepaymentSchedulePay> list = fsCaseRepaymentSchedulePayService.selectFsCaseRepaymentSchedulePayList(fsCaseRepaymentSchedulePay);
        Map<Long, String> zfMap = new HashMap<>();
        List<FsEntrust> entrusts = fsEntrustService.selectFsEntrustList(new FsEntrust());
        for (int i = 0; i < entrusts.size(); i++) {
            zfMap.put(entrusts.get(i).getId(), entrusts.get(i).getName());
        }
        Map<Long, String> userMap = new HashMap<>();
        List<SysUser> users = sysUserService.selectUserList(new SysUser());
        for (int i = 0; i < users.size(); i++) {
            userMap.put(users.get(i).getUserId(), users.get(i).getNickName());
        }
        for (int i = 0; i < list.size(); i++) {
            FsCaseRepaymentSchedulePay pay = list.get(i);
            FsCaseRepaymentSchedule schedule = fsCaseRepaymentScheduleService.selectFsCaseRepaymentScheduleById(pay.getScheduleId());
            FsCase fsCase = fsCaseService.selectFsCaseById(schedule.getCaseId());
            FsClient bg = fsClientService.selectFsClientById(fsCase.getBg());
            fsCase.setBgDsr(bg);
            if (fsCase.getZfid() != null) {
                fsCase.setZfName(zfMap.get(fsCase.getZfid()));
            }
            schedule.setFsCase(fsCase);
            if (schedule.getScr() != null) {
                schedule.setScrMc(userMap.get(schedule.getScr()));
            }
            FsCaseRepaymentScheduleFile fileQuery = new FsCaseRepaymentScheduleFile();
            fileQuery.setPayId(pay.getId());
            List<FsCaseRepaymentScheduleFile> files = fsCaseRepaymentScheduleFileService.selectFsCaseRepaymentScheduleFileList(fileQuery);
            pay.setFiles(files);
            pay.setSchedule(schedule);
        }
        return getDataTable(list);
    }

    /**
     * 导出还款计划支付列表
     */
    @PreAuthorize("@ss.hasPermi('fs:case:export')")
    @Log(title = "还款计划支付", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, FsCaseRepaymentSchedulePay fsCaseRepaymentSchedulePay) {
        List<FsCaseRepaymentSchedulePay> list = fsCaseRepaymentSchedulePayService.selectFsCaseRepaymentSchedulePayList(fsCaseRepaymentSchedulePay);
        Map<Long, String> zfMap = new HashMap<>();
        List<FsEntrust> entrusts = fsEntrustService.selectFsEntrustList(new FsEntrust());
        for (int i = 0; i < entrusts.size(); i++) {
            zfMap.put(entrusts.get(i).getId(), entrusts.get(i).getName());
        }
        Map<Long, String> userMap = new HashMap<>();
        List<SysUser> users = sysUserService.selectUserList(new SysUser());
        for (int i = 0; i < users.size(); i++) {
            userMap.put(users.get(i).getUserId(), users.get(i).getNickName());
        }
        for (int i = 0; i < list.size(); i++) {
            FsCaseRepaymentSchedulePay pay = list.get(i);
            FsCaseRepaymentSchedule schedule = fsCaseRepaymentScheduleService.selectFsCaseRepaymentScheduleById(pay.getScheduleId());
            FsCase fsCase = fsCaseService.selectFsCaseById(schedule.getCaseId());
            FsClient bg = fsClientService.selectFsClientById(fsCase.getBg());
            fsCase.setBgDsr(bg);
            if (fsCase.getZfid() != null) {
                fsCase.setZfName(zfMap.get(fsCase.getZfid()));
            }
            schedule.setFsCase(fsCase);
            if (schedule.getScr() != null) {
                schedule.setScrMc(userMap.get(schedule.getScr()));
            }
            pay.setSchedule(schedule);
        }
        try {
            InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("template/还款审核模板.xlsx");
            ExcelExporter.exportDataToTemplateForRepaymentScheduleSh(response, list, inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取还款计划支付详细信息
     */
    @PreAuthorize("@ss.hasPermi('fs:case:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        return success(fsCaseRepaymentSchedulePayService.selectFsCaseRepaymentSchedulePayById(id));
    }

    /**
     * 新增还款计划支付
     */
    @PreAuthorize("@ss.hasPermi('fs:case:add')")
    @Log(title = "还款计划支付", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody FsCaseRepaymentSchedulePay pay) {
        FsCaseRepaymentSchedulePay payQuery = new FsCaseRepaymentSchedulePay();
        payQuery.setScheduleId(pay.getScheduleId());
        List<FsCaseRepaymentSchedulePay> oldPays = fsCaseRepaymentSchedulePayService.selectFsCaseRepaymentSchedulePayList(payQuery);
        Set<Integer> oldZts = new HashSet<>();

        pay.setZt(0);
        fsCaseRepaymentSchedulePayService.insertFsCaseRepaymentSchedulePay(pay);

        FsCaseRepaymentSchedule schedule = fsCaseRepaymentScheduleService.selectFsCaseRepaymentScheduleById(pay.getScheduleId());

        if (StringUtils.isNotBlank(pay.getFileUrls())) {
            String[] urls = pay.getFileUrls().split(",");
            for (int i = 0; i < urls.length; i++) {
                String url = urls[i];
                String fileName = getFileNameByUrl(url);
                FsCaseRepaymentScheduleFile file = new FsCaseRepaymentScheduleFile();
                file.setPayId(pay.getId());
                file.setScheduleId(schedule.getId());
                file.setRepaymentId(schedule.getRepaymentId());
                file.setName(fileName);
                file.setOosUrl(url);
                fsCaseRepaymentScheduleFileService.insertFsCaseRepaymentScheduleFile(file);
            }
        }

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(schedule.getJhrq());
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1;
        FsRepaymentStatistic statistic = new FsRepaymentStatistic();
        statistic.setSsr(schedule.getSsr());
        statistic.setYear(year);
        statistic.setMonth(month);
        List<FsRepaymentStatistic> statistics = fsRepaymentStatisticService.selectFsRepaymentStatisticList(statistic);
        if (statistics.isEmpty()) {
            return error("无法找到统计信息，请联系管理员！");
        }
        statistic = statistics.get(0);
        BigDecimal oldPaysJe = BigDecimal.ZERO;
        if (!oldPays.isEmpty()) {
            for (int i = 0; i < oldPays.size(); i++) {
                oldPaysJe = oldPaysJe.add(oldPays.get(i).getShje());
                oldZts.add(oldPays.get(i).getZt());
            }
        }

        int dhnum = statistic.getDhnum();
        int dshnum = statistic.getDshnum();
        BigDecimal dhje = statistic.getDhje();
        BigDecimal dshje = statistic.getDshje();
        if (oldPays.isEmpty() || !oldZts.contains(0)) {
            dshnum++;
        }
        if (pay.getHklx() == 2) {
            dhnum--;
        }
        BigDecimal sdshje = oldPaysJe.add(pay.getShje());
        if (sdshje.compareTo(schedule.getJhje()) < 0) {
            dhje = dhje.subtract(pay.getShje());
        } else {
            if (oldPaysJe.compareTo(schedule.getJhje()) < 0) {
                dhje = dhje.subtract(schedule.getJhje().subtract(oldPaysJe));
            }
        }

        dshje = dshje.add(pay.getShje());
        statistic.setDhnum(dhnum);
        statistic.setDhje(dhje);
        statistic.setDshnum(dshnum);
        statistic.setDshje(dshje);

        fsRepaymentStatisticService.updateFsRepaymentStatistic(statistic);
        return success();
    }

    /**
     * 修改还款计划支付
     */
    @PreAuthorize("@ss.hasPermi('fs:case:edit')")
    @Log(title = "还款计划支付", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody FsCaseRepaymentSchedulePay pay) {
        FsCaseRepaymentSchedulePay old = fsCaseRepaymentSchedulePayService.selectFsCaseRepaymentSchedulePayById(pay.getId());

        BigDecimal change = pay.getShje().subtract(old.getShje());
        if (change.doubleValue() != 0) {
            FsCaseRepaymentSchedule schedule = fsCaseRepaymentScheduleService.selectFsCaseRepaymentScheduleById(pay.getScheduleId());

            Calendar calendar = Calendar.getInstance();
            calendar.setTime(schedule.getJhrq());
            int year = calendar.get(Calendar.YEAR);
            int month = calendar.get(Calendar.MONTH) + 1;
            FsRepaymentStatistic statistic = new FsRepaymentStatistic();
            statistic.setSsr(schedule.getSsr());
            statistic.setYear(year);
            statistic.setMonth(month);
            List<FsRepaymentStatistic> statistics = fsRepaymentStatisticService.selectFsRepaymentStatisticList(statistic);
            if (statistics.isEmpty()) {
                return error("无法找到统计信息，请联系管理员！");
            }
            statistic = statistics.get(0);
            BigDecimal dhje = statistic.getDhje();
            BigDecimal dshje = statistic.getDshje();
            dhje = dhje.subtract(change);
            dshje = dshje.add(change);
            statistic.setDhje(dhje);
            statistic.setDshje(dshje);

            fsRepaymentStatisticService.updateFsRepaymentStatistic(statistic);
        }

        return toAjax(fsCaseRepaymentSchedulePayService.updateFsCaseRepaymentSchedulePay(pay));
    }

    /**
     * 删除还款计划支付
     */
    @PreAuthorize("@ss.hasPermi('fs:case:remove')")
    @Log(title = "还款计划支付", businessType = BusinessType.DELETE)
    @DeleteMapping("/{id}")
    public AjaxResult remove(@PathVariable Long id) {
        FsCaseRepaymentSchedulePay pay = fsCaseRepaymentSchedulePayService.selectFsCaseRepaymentSchedulePayById(id);

        FsCaseRepaymentSchedule schedule = fsCaseRepaymentScheduleService.selectFsCaseRepaymentScheduleById(pay.getScheduleId());
        FsCase fsCase = fsCaseService.selectFsCaseById(schedule.getCaseId());
        FsCaseRepaymentScheduleFile file = new FsCaseRepaymentScheduleFile();
        file.setPayId(pay.getId());
        List<FsCaseRepaymentScheduleFile> files = fsCaseRepaymentScheduleFileService.selectFsCaseRepaymentScheduleFileList(file);
        for (int i = 0; i < files.size(); i++) {
            String path = "还款凭证/";
            if (fsCase.getZfid() == null) {
                path += "0/" + fsCase.getId();
            } else {
                path += fsCase.getZfid() + "/" + fsCase.getId();
            }
            ossUtil.delete(path, files.get(i).getName());
            fsCaseRepaymentScheduleFileService.deleteFsCaseRepaymentScheduleFileById(files.get(i).getId());
        }
        fsCaseRepaymentSchedulePayService.deleteFsCaseRepaymentSchedulePayById(id);
        FsCaseRepaymentSchedulePay payQuery = new FsCaseRepaymentSchedulePay();
        payQuery.setScheduleId(pay.getScheduleId());
        List<FsCaseRepaymentSchedulePay> pays = fsCaseRepaymentSchedulePayService.selectFsCaseRepaymentSchedulePayList(payQuery);
        Set<Integer> oldZts = new HashSet<>();
        Set<Integer> oldLxs = new HashSet<>();

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(schedule.getJhrq());
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1;
        FsRepaymentStatistic statistic = new FsRepaymentStatistic();
        statistic.setSsr(schedule.getSsr());
        statistic.setYear(year);
        statistic.setMonth(month);
        List<FsRepaymentStatistic> statistics = fsRepaymentStatisticService.selectFsRepaymentStatisticList(statistic);
        if (statistics.isEmpty()) {
            return error("无法找到统计信息，请联系管理员！");
        }

        statistic = statistics.get(0);
        BigDecimal paysJe = BigDecimal.ZERO;
        if (!pays.isEmpty()) {
            for (int i = 0; i < pays.size(); i++) {
                paysJe = paysJe.add(pays.get(i).getShje());
                oldZts.add(pays.get(i).getZt());
                oldLxs.add(pays.get(i).getHklx());
            }
        }
        oldZts.add(pay.getZt());
        oldLxs.add(pay.getHklx());

        int dhnum = statistic.getDhnum();
        int dshnum = statistic.getDshnum();
        BigDecimal dhje = statistic.getDhje();
        BigDecimal dshje = statistic.getDshje();
        if (pays.isEmpty()) {
            dshnum--;
        } else {
            if (!oldZts.contains(0)) {
                dshnum--;
            }
        }
        if (oldLxs.contains(2)) {
            dhnum++;
            for (int i = 0; i < pays.size(); i++) {
                if (pays.get(i).getHklx() == 2) {
                    pays.get(i).setHklx(1);
                    fsCaseRepaymentSchedulePayService.updateFsCaseRepaymentSchedulePay(pays.get(i));
                }
            }
        }
        BigDecimal odshje = paysJe.add(pay.getShje());
        if (odshje.compareTo(schedule.getJhje()) < 0) {
            dhje = dhje.add(pay.getShje());
        } else {
            if (paysJe.compareTo(schedule.getJhje()) < 0) {
                dhje = dhje.add(pay.getShje()).subtract(odshje.subtract(schedule.getJhje()));
            }
        }

        dshje = dshje.subtract(pay.getShje());
        statistic.setDhnum(dhnum);
        statistic.setDhje(dhje);
        statistic.setDshnum(dshnum);
        statistic.setDshje(dshje);

        fsRepaymentStatisticService.updateFsRepaymentStatistic(statistic);
        return success();
    }

    /**
     * 修改还款计划支付
     */
    @PreAuthorize("@ss.hasPermi('fs:case:edit')")
    @Log(title = "还款计划支付", businessType = BusinessType.UPDATE)
    @GetMapping(value = "/sh/{id}")
    public AjaxResult sh(@PathVariable("id") Long id) {
        FsCaseRepaymentSchedulePay pay = fsCaseRepaymentSchedulePayService.selectFsCaseRepaymentSchedulePayById(id);
        pay.setZt(1);
        FsCaseRepaymentSchedulePay payQuery = new FsCaseRepaymentSchedulePay();
        payQuery.setScheduleId(pay.getScheduleId());
        List<FsCaseRepaymentSchedulePay> pays = fsCaseRepaymentSchedulePayService.selectFsCaseRepaymentSchedulePayList(payQuery);

        Set<Integer> oldZts = new HashSet<>();
        Set<Integer> oldLxs = new HashSet<>();

        FsCaseRepaymentSchedule schedule = fsCaseRepaymentScheduleService.selectFsCaseRepaymentScheduleById(pay.getScheduleId());

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(schedule.getJhrq());
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1;
        FsRepaymentStatistic statistic = new FsRepaymentStatistic();
        statistic.setSsr(schedule.getSsr());
        statistic.setYear(year);
        statistic.setMonth(month);
        List<FsRepaymentStatistic> statistics = fsRepaymentStatisticService.selectFsRepaymentStatisticList(statistic);
        if (statistics.isEmpty()) {
            return error("无法找到统计信息，请联系管理员！");
        }

        statistic = statistics.get(0);
        BigDecimal paysJe = BigDecimal.ZERO;
        if (!pays.isEmpty()) {
            for (int i = 0; i < pays.size(); i++) {
                paysJe = paysJe.add(pays.get(i).getShje());
                oldZts.add(pays.get(i).getZt());
                oldLxs.add(pays.get(i).getHklx());
            }
        }
        int dshnum = statistic.getDshnum();
        int yhnum = statistic.getYhnum();
        BigDecimal dshje = statistic.getDshje();
        BigDecimal yhje = statistic.getYhje();

        yhje = yhje.add(pay.getShje());
        dshje = dshje.subtract(pay.getShje());
        statistic.setYhje(yhje);
        statistic.setDshje(dshje);
        if (!oldZts.contains(1)) {
            yhnum++;
        }
        fsCaseRepaymentSchedulePayService.updateFsCaseRepaymentSchedulePay(pay);
        payQuery = new FsCaseRepaymentSchedulePay();
        payQuery.setScheduleId(pay.getScheduleId());
        payQuery.setZt(0);
        pays = fsCaseRepaymentSchedulePayService.selectFsCaseRepaymentSchedulePayList(payQuery);
        schedule.setZt(1);
        if (pays.isEmpty()) {
            dshnum--;
            if (oldLxs.contains(2)) {
                schedule.setZt(2);
            }
        }
        statistic.setYhnum(yhnum);
        statistic.setDshnum(dshnum);
        fsCaseRepaymentScheduleService.updateFsCaseRepaymentSchedule(schedule);
        fsRepaymentStatisticService.updateFsRepaymentStatistic(statistic);

        return success();
    }

    private String getFileNameByUrl(String url) {
        url = URLDecoder.decode(url);
        url = url.split("\\?")[0];
        System.out.println(url);
        int index = url.lastIndexOf("/") + 1;
        String fileName = url.substring(index, url.length());
        return fileName;
    }

    /**
     * 删除还款计划支付文件
     */
    @PreAuthorize("@ss.hasPermi('fs:case:edit')")
    @Log(title = "还款计划支付", businessType = BusinessType.DELETE)
    @DeleteMapping("/file/{scheduleId}/{payId}/{name}")
    public AjaxResult removeFile(
            @PathVariable("name") String name,
            @PathVariable("payId") Long payId,
            @PathVariable("scheduleId") Long scheduleId) {
        FsCaseRepaymentSchedule schedule = fsCaseRepaymentScheduleService.selectFsCaseRepaymentScheduleById(scheduleId);
        FsCase fsCase = fsCaseService.selectFsCaseById(schedule.getCaseId());
        String path = "还款凭证/";
        if (fsCase.getZfid() == null) {
            path += "0/" + fsCase.getId();
        } else {
            path += fsCase.getZfid() + "/" + fsCase.getId();
        }
        ossUtil.delete(path, name);
        FsCaseRepaymentScheduleFile file = new FsCaseRepaymentScheduleFile();
        file.setScheduleId(schedule.getId());
        if (payId != null) {
            file.setPayId(payId);
        }
        file.setName(name);
        List<FsCaseRepaymentScheduleFile> files = fsCaseRepaymentScheduleFileService.selectFsCaseRepaymentScheduleFileList(file);
        for (int i = 0; i < files.size(); i++) {
            fsCaseRepaymentScheduleFileService.deleteFsCaseRepaymentScheduleFileById(files.get(i).getId());
        }
        return success();
    }

}
